package de.revdev.llt.module.classroom;

import de.revdev.llt.module.filecardboxes.FileCardBox;
import de.revdev.llt.module.learning.LearnStatusFCB;
import de.revdev.llt.module.learning.LearnStatusFCBFacade;
import de.revdev.llt.module.useradministrtaion.UserBean;
import de.revdev.llt.module.useradministrtaion.UserFacade;
import java.io.Serializable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.faces.event.ActionEvent;
import javax.faces.model.ListDataModel;
import javax.inject.Inject;
import javax.inject.Named;

/**
 *
 * @author f.lindermaier
 */
@Named(value = "puCRViewBean")
@SessionScoped
public class PuCRViewBean implements Serializable {

    private UserBean userBean;
    private PublicClassRoomFacade pcrf;
    private UserFacade uf;
    private LearnStatusFCBFacade lsfcbf;
    private ParticipantsFacade pf;
    private static final Logger log = Logger.getLogger(PuCRViewBean.class.getName());
    private List<PublicClassRoom> ownPublicClassRooms;
    private List<PublicClassRoom> foreignPublicClassRooms;
    private List<Participants> invitations;
    private PublicClassRoom newPuCR;
    private PublicClassRoom opendPuCR;
    private ListDataModel<PublicClassRoom> ownPublicCRDataModel;
    private ListDataModel<PublicClassRoom> foreignPublicCRDataModel;
    private ListDataModel<FileCardBox> fileCardBoxDataModel;
    private ListDataModel<Participants> invitationDataModel;
    private String templateString;

    /**
     * Creates a new instance of PuCRViewBean
     */
    public PuCRViewBean() {
    }

    @PostConstruct
    private void init() {
        newPuCR = new PublicClassRoom();
        ownPublicCRDataModel = new ListDataModel<>();
        foreignPublicCRDataModel = new ListDataModel<>();
    }

    public void preRenderListenenr() {
        ownPublicClassRooms = pcrf.getOwnPublicClassRooms(userBean.getUser());
        foreignPublicClassRooms = pcrf.getForeignPublicClassRooms(userBean.getUser(), Boolean.TRUE);
        invitations = pf.getInvitations(userBean.getUser());
        invitationDataModel = new ListDataModel<>(invitations);
    }

    public ListDataModel<PublicClassRoom> getOwnPublicCRDataModel() {
        if (ownPublicClassRooms == null) {
            ownPublicClassRooms = pcrf.getOwnPublicClassRooms(userBean.getUser());
        }
        ownPublicCRDataModel = new ListDataModel<>(ownPublicClassRooms);
        return ownPublicCRDataModel;
    }

    public ListDataModel<PublicClassRoom> getForeignPublicCRDataModel() {
        if (foreignPublicClassRooms == null) {
            foreignPublicClassRooms = pcrf.getForeignPublicClassRooms(userBean.getUser(), Boolean.TRUE);
        }
        foreignPublicCRDataModel = new ListDataModel<>(foreignPublicClassRooms);
        return foreignPublicCRDataModel;
    }

    public boolean hasInvitations() {
        invitations = pf.getInvitations(userBean.getUser());
        invitationDataModel = new ListDataModel<>(invitations);
        return !invitations.isEmpty();
    }

    public void acceptInvitation(ActionEvent event) {
        Participants p = invitationDataModel.getRowData();
        p.setAccepted(true);
        pf.edit(p);
        log.log(Level.INFO, "Invitation {0} accepted from User {1}", new Object[]{p.getId(), userBean.getUser().getId()});
        invitations = pf.getInvitations(userBean.getUser());
        invitationDataModel = new ListDataModel<>(invitations);

        foreignPublicClassRooms = pcrf.getForeignPublicClassRooms(userBean.getUser(), Boolean.TRUE);
        foreignPublicCRDataModel = new ListDataModel<>(foreignPublicClassRooms);
    }

    public void rejectInvitation(ActionEvent event) {
        Participants p = invitationDataModel.getRowData();
        pf.remove(p);
        userBean.getUser().getParticipants().remove(p);
        p.getPublicClassRoom().getParticipants().remove(p);
        uf.edit(userBean.getUser());
        pcrf.edit(p.getPublicClassRoom());
        log.log(Level.INFO, "Invitation {0} rejected from User {1}", new Object[]{p.getId(), userBean.getUser().getId()});
    }

    public void leavePuCR(ActionEvent event) {
        PublicClassRoom pcr = foreignPublicCRDataModel.getRowData();
        pcr = pcrf.getFCBforPuCR(pcr);
        for (FileCardBox fcb : pcr.getFileCardBoxes()) {
            LearnStatusFCB ls = lsfcbf.getLearnStatusForFileCardBox(userBean.getUser(), fcb);
            if (ls != null) {
                lsfcbf.remove(ls);
                userBean.getUser().getLearnStatusFCBs().remove(ls);
                log.log(Level.INFO, "LearnStatusFCB {0} was deleted", ls.getId());
            }
        }
        Participants p = pf.getParticipation(userBean.getUser(), pcr);
        pf.remove(p);
        userBean.getUser().getParticipants().remove(p);
        pcr.getParticipants().remove(p);
        log.log(Level.INFO, "Participation {0} was deleted", p.getId());
        uf.edit(userBean.getUser());
        pcrf.edit(pcr);
        foreignPublicClassRooms = pcrf.getForeignPublicClassRooms(userBean.getUser(), Boolean.TRUE);
        foreignPublicCRDataModel = new ListDataModel<>(foreignPublicClassRooms);
    }

    public void deletePuCR() {
        userBean.getUser().getPublicClassRooms().remove(ownPublicCRDataModel.getRowData());
        pcrf.remove(ownPublicCRDataModel.getRowData());
        log.log(Level.INFO, "PubicClassRoom {0} was deleted", ownPublicCRDataModel.getRowData().getId());
    }

    public void saveNewOwnPCR() {
        newPuCR.setOwner(userBean.getUser());
        pcrf.create(newPuCR);
        log.log(Level.INFO, "PubicClassRoom {0} was created", newPuCR.getId());
        userBean.getUser().getPublicClassRooms().add(newPuCR);
        uf.edit(userBean.getUser());
        newPuCR = new PublicClassRoom();
    }

    public void cancelNewOwnPCR() {
        newPuCR = new PublicClassRoom();
    }

    public boolean maxOwnClassRoomReached() {
        if (ownPublicClassRooms != null && ownPublicClassRooms.size() >= 2) {
            return true;
        }
        return false;
    }

    public int cntOwnPCRFCB() {
        if (ownPublicCRDataModel.getRowData().getFileCardBoxes() != null) {
            return ownPublicCRDataModel.getRowData().getFileCardBoxes().size();
        } else {
            return 0;
        }
    }

    public int cntOwnPCRUser() {
        if (ownPublicCRDataModel.getRowData().getFileCardBoxes() != null) {
            return ownPublicCRDataModel.getRowData().getParticipants().size() + 1;
        } else {
            return 1;
        }
    }

    public boolean roleAdmin() {
        for (Participants p : opendPuCR.getParticipants()) {
            if (p.getUser().equals(userBean.getUser()) && p.getClassRoomRole().equals(Participants.ClassRoomRole.ADMIN)) {
                return true;
            }
        }
        return opendPuCR.getOwner().equals(userBean.getUser());
    }

    @Inject
    public void setUserBean(UserBean userBean) {
        this.userBean = userBean;
    }

    @Inject
    public void setPublicClassRoomFacade(PublicClassRoomFacade publicClassRoomFacade) {
        this.pcrf = publicClassRoomFacade;
    }

    @Inject
    public void setUserFacade(UserFacade userFacade) {
        this.uf = userFacade;
    }

    @Inject
    public void setLearnStatusFCBFacade(LearnStatusFCBFacade learnStatusFCBFacade) {
        this.lsfcbf = learnStatusFCBFacade;
    }

    @Inject
    public void setParticipantsFacade(ParticipantsFacade participantsFacade) {
        this.pf = participantsFacade;
    }

    public PublicClassRoom getNewPuCR() {
        return newPuCR;
    }

    public void setNewPuCR(PublicClassRoom newPuCR) {
        this.newPuCR = newPuCR;
    }

    public PublicClassRoom getOpendPuCR() {
        return opendPuCR;
    }

    public void setOpendPuCR(PublicClassRoom opendPuCR) {
        this.opendPuCR = opendPuCR;
    }

    public ListDataModel<FileCardBox> getFileCardBoxDataModel() {
//        opendPuCR = pcrf.find(opendPuCR.getId());
//        fileCardBoxDataModel = new ListDataModel<>(opendPuCR.getFileCardBoxes());
        return fileCardBoxDataModel;
    }

    public void setFileCardBoxDataModel(ListDataModel<FileCardBox> fileCardBoxDataModel) {
        this.fileCardBoxDataModel = fileCardBoxDataModel;
    }

    public String getTemplateString() {
        return templateString;
    }

    public void setTemplateString(String templateString) {
        this.templateString = templateString;
    }

    public List<Participants> getInvitations() {
        return invitations;
    }

    public void setInvitations(List<Participants> invitations) {
        this.invitations = invitations;
    }

    public ListDataModel<Participants> getInvitationDataModel() {
        return invitationDataModel;
    }

    public void setInvitationDataModel(ListDataModel<Participants> invitationDataModel) {
        this.invitationDataModel = invitationDataModel;
    }
}
